
package com.NeuglsWorkStudio.Colors
{
	/**
	 * HSL class is used to convert the HSL color to RGB color
	 * */
	public class HSL {
		private var luminance:Number;
		private var saturation:Number;
		private var hue:Number;
		
		/**
		 * Contructs an HSL object for containing Hue Saturation and Luminance values, and
		 * converting them to an RGB or Hex color
		 * @param	h Hue (0-360)
		 * @param	s Saturation(0-1)
		 * @param	l Luminance(0-1)
		 */
		public function HSL(h:Number=0, s:Number=1, l:Number=.5) {
			hue = h;
			saturation = s;
			luminance = l;
		}
		
		/*
		* Getters for each channel
		*/
		public function get Hue():Number {
			return hue;
		}
		public function get Saturation():Number {
			return saturation;
		}
		public function get Luminance():Number {
			return luminance;
		}
		/*
		*Setters for each channel
		*/
		public function set Hue(Value:Number):void {
			hue = (Value>360)? Value-360 : ((Value<0)?Value+360:Value);
		}
		public function set Saturation(Value:Number):void {
			saturation = (Value>1)? 1 : ((Value<0)?0:Value);
		}
		public function set Luminance(Value:Number):void {
			luminance = (Value>1)? 1 : ((Value<0)?0:Value);
		}
		/**
		 * Converts the HSL object to an RGB object defining the same color
		 * @return RGB object
		 */
		public function toRGB():RGB{
			return getRGB(hue, saturation, luminance);
		}
		/**
		 * Converts the HSL object to a Hex value defining the same color
		 * @return Hex value of HSL color
		 */
		public function toHex():uint {
			return toRGB().Hex;
		}
		
		/**
		 * Static method for directly converting HSL values to Hex
		 * @param	h Hue (0-360)
		 * @param	s Saturation(0-1)
		 * @param	l Luminance(0-1)
		 * @return a Hex value represnting the given HSL values
		 */
		public static function getHex(h:Number, s:Number, l:Number):uint{
			return getRGB(h, s, l).Hex;
		}
		/**
		 * Static method for directly converting HSL values to
		 * an RGB object
		 * @param	h Hue (0-360)
		 * @param	s Saturation(0-1)
		 * @param	l Luminance(0-1)
		 * @return an RGB object represnting the given HSL values
		 */
		public static function getRGB(h:Number, s:Number, l:Number):RGB{
			h = h / 360;
			var r:Number;
			var g:Number;
			var b:Number;
			
			if(l==0)
			{
				r=g=b=0;
			}
			else
			{
				if(s == 0)
				{
					r=g=b=l;
				}
				else
				{
					var t2:Number = (l<=0.5)? l*(1+s):l+s-(l*s);
					var t1:Number = 2*l-t2;
					var t3:Vector.<Number> = new Vector.<Number>();
					t3.push(h+1/3);
					t3.push(h);
					t3.push(h-1/3);
					var clr:Vector.<Number> = new Vector.<Number>();
					clr.push(0);
					clr.push(0);
					clr.push(0);
					for(var i:int=0;i<3;i++)
					{
						if(t3[i]<0)
							t3[i]+=1;
						if(t3[i]>1)
							t3[i]-=1;
						
						if(6*t3[i] < 1)
							clr[i]=t1+(t2-t1)*t3[i]*6;
						else if(2*t3[i]<1)
							clr[i]=t2;
						else if(3*t3[i]<2)
							clr[i]=(t1+(t2-t1)*((2/3)-t3[i])*6);
						else
							clr[i]=t1;
					}
					r=clr[0];
					g=clr[1];
					b=clr[2];
				}
			}
			return new RGB(int(r*255),int(g*255),int(b*255));
		}
		
		public static function RGB2HSL(rgb:uint):HSL{
		//计算算法请参照：http://bbs.9ria.com/thread-26029-1-1.html
			var r:Number = (rgb>>16) % 256;
			var g:Number = (rgb>>8) % 256;
			var b:Number = rgb % 256;
			r/=255;
			g/=255;
			b/=255;
			var min:Number;
			var max:Number;
		
			var h:Number;
			var s:Number;
			var l:Number;
			
			min=Math.min(r,g,b);
			max=Math.max(r,g,b);
			
			//calc l
			l=(min+max)/2;
			
			//calc s
			
			if(l==0||max==min){
				s=0;
			}
			if(l>0&&l<=0.5){
				s=(max-min)/(2*l);
			}
			if(l>0.5){
				s=(max-min)/(2-2*l);
			}
			
			
			if(min==max){
				h=0;
				s=0;
				return new HSL(h,s,l);
			}
			
			if(max==r){
				h=60*(g-b)/(max-min);
				if(g<b){
					h+=360;
				}
				return new HSL(h,s,l);
			}
			
			if(max==g){
				h=60*(b-r)/(max-min)+120;
			}
			if(max==b){
				h=60*(r-g)/(max-min)+240;
			}
			return new HSL(h,s,l);
		}
		
		/**
		 * Add more light to the specified color
		 * */
		
		public static function AddLightToColor(Color:int,MoreLight:Number):int{
			var b:HSL=HSL.RGB2HSL(Color);
			return new HSL(b.hue,b.saturation,b.luminance+MoreLight).toRGB().Hex;
		}
		
		public static function AddSaturation(Color:int,H:Number,S:Number,L:Number):int{
			var b:HSL=HSL.RGB2HSL(Color);
			return new HSL(b.hue+H,b.saturation+S,b.luminance+L).toRGB().Hex;
		}

	}
	
}